// #define LWIP_NETIF_HOSTNAME 1
#include "fallback.h"
#include "common_def.h"
#include "osal_debug.h"
#include "cmsis_os2.h"
#include "app_init.h"
#include "los_queue.h"
#include "los_event.h"
#include "los_swtmr.h"
#include "los_task.h"
#include "gpio.h"
#include "pinctrl.h"
#include "i2c.h"
#include "iot_i2c.h"
#include "uart.h"
#include "unistd.h"
#include "nv.h"
#include "hal_cipher_trng.h"
#include "los_sem.h"


#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-label"
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#pragma GCC diagnostic ignored "-Waddress"
#pragma GCC diagnostic ignored "-Wlogical-not-parentheses"
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
#pragma GCC diagnostic ignored "-Wint-conversion"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wpointer-sign"

#define NV_KEY_MAC KEY_ID_REGION1

#ifdef WIFI_DEVICE_C_H
#include "lwip/netifapi.h"
#endif

#ifdef CSNETWORK_CLIENT_H
#include "async_http_client.h"

#define TO_STR(x) #x
#define EXPAND_AND_STRINGIFY(x) TO_STR(x)

#define sendMessageToServer(server_sence, title, message) \
    _sendMessageToServer(vm, fsm, EXPAND_AND_STRINGIFY(PROJECT_ID), server_sence, title, message)

#endif
#define printf osal_printk
#define exit(a) abort()
#define _OB_LOG_LEVEL 5

STATIC UINT32 rs_queue_id;


#define I2C_MASTER_ADDR                   0x0
#define I2C_SET_BAUDRATE                  400000
#define I2C_MASTER_PIN_MODE               2
#define I2C_SCL_MASTER_PIN                15
#define I2C_SDA_MASTER_PIN                16
#define I2C_MASTER_BUS_ID                 1

static int seed;
static int ob_rand(void)
{
	int rnd;
	// srand(seed * osKernelGetSysTimerCount() * rand());
	seed = rand();
	return seed;
}
static void hi_io_set_func_gpio(unsigned int pin){
	uapi_pin_set_mode(pin, 0);
}
static void hi_io_set_func_pwm(unsigned int pin){
	uapi_pin_set_mode(pin, 1);
}
#ifdef HI_ADC_H
#include "adc.h"
float hi_adc_convert_to_voltage(unsigned int data)
{
    float voltage = (float)data * 1.8 * 4 / 4096; /* adc code equals: voltage/4/1.8*4096  */
    return voltage;
}
#define ADC_CHANNEL_MAX_NUM 6
uint32_t adc_data [ADC_CHANNEL_MAX_NUM];
static unsigned int adcChannelByPin(unsigned int pin){
	switch(pin){
		case 7:
			pin = 0;
			break;
		case 12:
			pin = 5;
			break;
		case 8:
			pin = 1;
			break;
		case 10:
			pin = 3;
			break;
		case 11:
			pin = 4;
			break;
		case 9:
			pin = 2;
			break;
		default:
			return -1;
	}
	return pin;
}
void adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next) 
{ 
     UNUSED(next);
    adc_data[ch] = buffer[length - 1];
	printf("adc_callback: ch:%d, data:%d\r\n",ch, buffer[length - 1]);
}
static long analogRead(unsigned int pin){
	pin = adcChannelByPin(pin);
    return adc_data[pin];
}
static void ADC_Start(unsigned int pin){
	pin = adcChannelByPin(pin);
    adc_scan_config_t config = {
        .type = 0,
        .freq = 1,
    };
	printf("adc_scan_ch_enable channel:%d\r\n",pin);
    errcode_t e = uapi_adc_auto_scan_ch_enable(pin, config, adc_callback);
	if(e!=ERRCODE_SUCC){
		printf("adc_scan_ch_enable fail:%d\r\n",e);
	}
}
#endif
#ifdef IOT_PWM_H
#include "pwm.h"
static unsigned int getPwmIdOfGPIO(unsigned int pin){
	unsigned int pwmId= 0;
	switch(pin){
		case 5:
		 pwmId = 5;
		 break;
		case 7:
		 pwmId = 7;
		 break;
		case 6:
		 pwmId = 6;
		 break;
		case 3:
		 pwmId = 3;
		 break;
		case 2:
		 pwmId = 2;
		 break;
		case 0:
		 pwmId = 0;
		 break;
		case 12:
		 pwmId = 4;
		 break;
		case 1:
		 pwmId = 1;
		 break;
		case 8:
		 pwmId = 0;
		 break;
		case 10:
		 pwmId = 2;
		 break;
		case 11:
		 pwmId = 3;
		 break;
		case 9:
		 pwmId = 1;
		 break;
	}
	return pwmId;
}
static void rs_IoTPwmInit(unsigned int pin){
	uapi_pwm_init();
	unsigned int pwmId= getPwmIdOfGPIO(pin);
    IoTPwmInit(pwmId);
}
static void rs_IoTPwmStart(unsigned int pin, unsigned short duty, unsigned int freq){
	unsigned int port = getPwmIdOfGPIO(pin);
    errcode_t r = IoTPwmStart(port,  duty,  freq);
	if(r!=ERRCODE_SUCC){
		printf("IoTPwmStart fail:%d port:%d / %d\r\n",r,port,CONFIG_PWM_GROUP_NUM);
	}
}
static void rs_IoTPwmStop(unsigned int pin){
	unsigned int port = getPwmIdOfGPIO(pin);
    IoTPwmStop(port);
}
static void rs_IoTPwmDeinit(unsigned int pin){
	unsigned int port = getPwmIdOfGPIO(pin);
    IoTPwmDeinit(port);
}
#endif
#define hi_io_set_pull uapi_pin_set_pull

#ifdef IOT_GPIO_H
typedef struct{
	unsigned int id;
	char *arg;
	FSM_PTR fsm;
}BothIsr;
static void rs_IsrTrigger_0(BothIsr* arg);
static void rs_IsrTrigger_1(BothIsr* arg);
static void rs_IsrTrigger_both(BothIsr* arg);
static void rs_IoTGpioRegisterIsrFunc_(FSM_PTR fsm,unsigned int id,IotGpioIntPolarity intPolarity, char *arg){
	if(intPolarity==2){
		IotGpioValue v;
		BothIsr *arg_=(BothIsr*)calloc(1,sizeof(BothIsr));;
		arg_->id=id;arg_->arg=arg;
		arg_->fsm=fsm;
		IoTGpioGetInputVal(id, &v);
    	gpio_select_core(id, CORES_APPS_CORE);
		IoTGpioRegisterIsrFunc( id, IOT_INT_TYPE_EDGE,  v?0:1, rs_IsrTrigger_both, arg_);
	}else{
		BothIsr *arg_=(BothIsr*)calloc(1,sizeof(BothIsr));;
		arg_->id=id;arg_->arg=arg;
		arg_->fsm=fsm;
    	gpio_select_core(id, CORES_APPS_CORE);
		IoTGpioRegisterIsrFunc( id, IOT_INT_TYPE_EDGE,  intPolarity, intPolarity?rs_IsrTrigger_1:rs_IsrTrigger_0, arg_);
	}
}
#define rs_IoTGpioRegisterIsrFunc(id,intPolarity,arg) rs_IoTGpioRegisterIsrFunc_(fsm,id,intPolarity,arg) 

static int rs_IoTGpioGetInputVal(unsigned int pin){
	IotGpioValue v;
	IoTGpioGetInputVal(pin, &v);
	return v;
}

#endif


#ifdef __SSD1306_H__
static void ssd1306_DrawASCIIString(char* str, int i_Font, SSD1306_COLOR color){
	switch(i_Font){
		case 0:
			ssd1306_DrawString(str, Font_6x8, color);
			break;
		case 1:
			ssd1306_DrawString(str, Font_7x10, color);
			break;
		case 2:
			ssd1306_DrawString(str, Font_11x18, color);
			break;
		case 3:
			ssd1306_DrawString(str, Font_16x26, color);
			break;
	}
}
typedef struct{
	const uint8_t FontWidth;    /*!< Font width in pixels */
	uint8_t FontHeight;   /*!< Font height in pixels */
	char *data; /*!< Pointer to data font data array */
	const uint16_t bytesPerChar;
	unsigned char *index;
	const uint16_t indexLen;
	const uint16_t charCount;
}BitmapFontDef;

static BitmapFontDef getBitmapFont(char* name);

BITMAP_FUNCTION

static void ssd1306_DrawUTF8String(char* content,char* fontName,SSD1306_COLOR color){
	BitmapFontDef font = getBitmapFont(fontName);
	uint16_t len = strlen((char*)content);
	for(uint16_t i = 0;i<len;){
		unsigned short codepoint = 0xff & content[i];
		char codeLen = 1;
		if((codepoint & 0x80) == 0){
			// codeLen = 1;
		}else{
			if ((codepoint & 0b11100000) == 0b11000000) // 如果前两位为10，说明这是一个双字节字符
        	{
				codeLen = 2;
			}
    		else if ((codepoint & 0b11110000) == 0b11100000) // 如果前三位为110，说明这是一个三字节字符
        	{
				codeLen = 3;
			}
    		else if ((codepoint & 0b11111000) == 0b11110000) // 如果前四位为1110，说明这是一个四字节字符
        	{
				codeLen = 4;
			}else{
				printf("utf8 codepoint invalid %hu %hu\r\n",i,codepoint);
				abort();
			}
		}
		char *search = content+i;
		unsigned char *target = NULL;
		if(codeLen == 1 && search[0]==0x20){
		// 如果是空格直接取结果
			target = font.index;
		}else{
			// 否则遍历查找
			unsigned char *ps = font.index;
			while(true){
				size_t len = font.indexLen-(ps-font.index)-codeLen;
				ps = memchr(ps,search[0],len);
				if(ps == NULL){
				printf("not found , use space.\n");
					// 没找到，用空格代替
					target = font.index;
					break;
				}else{
					if(memcmp(ps,search,codeLen)==0){
						target = ps - 5; // 减去5是因为rl_memchr返回的是第一个匹配的位置
						break;
					}else{
						ps++;
					}
				}
			}
		}
		uint32_t idx = ((target)[1]<<16) | ((target)[2]<<8) | (target)[3];
		if(idx>=((uint32_t)font.charCount)*font.bytesPerChar-font.bytesPerChar){
			idx = 0;
			printf("idx overflow\n");
		}
		uint16_t* fd = font.data + idx*font.bytesPerChar;
		for(uint16_t y = 0;y<font.FontHeight;y++){
			for(uint16_t x = 0;x<font.FontWidth;x++){
				uint16_t bit = y*font.FontWidth+x;
				uint16_t ch = fd[bit/16];
				ch = (ch>>(bit%16))&1;
				if(ch){
					ssd1306_DrawPixel(ssd1306_GetCursorX()+x,ssd1306_GetCursorY()+y,color);
				}else{
					ssd1306_DrawPixel(ssd1306_GetCursorX()+x,ssd1306_GetCursorY()+y,!color);
				}
			}
		}
		ssd1306_SetCursor(ssd1306_GetCursorX()+font.FontWidth, ssd1306_GetCursorY());
		i+=codeLen;
	}
}
#endif

#ifdef IOT_UART_H
unsigned int r_IoTUartInit(unsigned int id,unsigned int baudRate, 
	unsigned int dataBits, unsigned int stopBits, unsigned int parity)
{
    uapi_uart_deinit(id); // 重点，UART初始化之前需要去初始化，否则会报0x80001044
	if(id==0){
	}
	else if(id==1){
	}
	else if(id==2){
	}else{
		return 1;
	}
	printf("uart%d init\r\n",id);
	IotUartAttribute param = {
		.baudRate = baudRate,
		.dataBits = dataBits,
		.stopBits  = stopBits,
		.parity   = parity,
		.rxBlock = 0,
		.txBlock = 0,
		.pad = 0
	};
	return IoTUartInit(id, &param);
}

size_t r_IoTUartRead(OB_VM* vm,unsigned int id,unsigned int maxLength){
	size_t list_ptr = OB_New_List( vm , 0,"OB_List-r_IoTUartRead");
	unsigned char* data = (unsigned char*)calloc(maxLength,sizeof(unsigned char));
	for(int i = 0 ; i < 10;i++){
		int size = IoTUartRead( id, data, maxLength);
		if(size<0){
			continue;
		}
		if(size>0){
			for(int i=0;i<size;i++){
				unsigned char c = data[i];
				OB_Insert_Value_At_Index( vm, list_ptr, i,(unsigned int)c);
			}
		}
		break;
	}
	free(data);
	return list_ptr;
}

int r_IoTUartWrite(OB_VM* vm,unsigned int id, size_t list_ptr){
	OB_List* list = (OB_List*)GetOBNObj(vm, list_ptr);
	
    size_t items_ptr = list->items_ptr;
	OB_List_Item* items = (OB_List_Item*)GetOBNObj(vm, items_ptr);

	unsigned char *data = calloc(list->length,sizeof(unsigned char));
	for(size_t i =0;i<list->length;i++){
		data[i] = (unsigned char)(items[i].i64);
	}
	unsigned int r = IoTUartWrite(id, data, list->length);
	free(data);
	return r;
}
#endif
typedef struct{
	OB_Message msg;
	size_t nativeObjSize;
	void* nativeObj;
	FSM_PTR fsm;
}AsyncMessage;

#ifdef SERVICE_WIFI_DEVICE_C_H
#include "lwip/netifapi.h"
#include "lwip/netif.h"

#define IsWifiActive wifi_is_sta_enabled
#define DisableWifi wifi_sta_disable
#define Scan wifi_sta_scan
#define WifiConnState wifi_conn_state_enum
#define WifiErrorCode errcode_t
#define WifiScanInfo wifi_scan_info_stru
#define securityType security_type

static int bitAnd(int a, int b)
{
    return a & b;
}
static int GetDeviceMacAddressText(char *result)
{
    u8_t buf[6] = {0};
	wifi_get_base_mac_addr(buf,6);
    if (buf != NULL)
    {
        sprintf_s(result, 18, "%02X%02X%02X%02X%02X%02X",
                  bitAnd(0xFF, buf[0]),
                  bitAnd(0xFF, buf[1]),
                  bitAnd(0xFF, buf[2]),
                  bitAnd(0xFF, buf[3]),
                  bitAnd(0xFF, buf[4]),
                  bitAnd(0xFF, buf[5]));
        return 0;
    }
    else
    {
        sprintf_s(result, 18, "MAC not found");
        return 1;
    }
}

char mac_set = 0;
int EnableWifi(void){
	if(wifi_is_sta_enabled()==1){
		return 0;
	}
	int r = wifi_sta_enable();
	if(r != 0){
		return r;
	}
	if(mac_set == 0){
		struct netif *netif = netifapi_netif_find("wlan0");
		u8_t saved[16] = {0};
		uint16_t readedLength;
		uapi_nv_read(NV_KEY_MAC, 16,&readedLength, saved);
		printf("\r\nreaded %d MAC:%02X%02X%02X%02X%02X%02X\r\n",
					readedLength,
					bitAnd(0xFF, saved[0]),
					bitAnd(0xFF, saved[1]),
					bitAnd(0xFF, saved[2]),
					bitAnd(0xFF, saved[3]),
					bitAnd(0xFF, saved[4]),
					bitAnd(0xFF, saved[5]));
		char mac[18];
		if(saved[0]+saved[1]+saved[2]+saved[3]+saved[4]+saved[5] == 0){
			u8_t *buf = netif->hwaddr;
			memcpy_s(saved,6, buf, 6);
			uapi_nv_write(NV_KEY_MAC, saved, 16);
			uapi_nv_flush();
			GetDeviceMacAddressText(mac);
			printf("mac address saved %s\r\n",mac);
		}
	}
    return (r);
}

static char g_target_ssid[WIFI_MAX_SSID_LEN];
static char g_target_key[WIFI_MAX_KEY_LEN];
errcode_t ScanAndConnectToWifi(const char* ssid,const char* key){
	EnableWifi();
	wifi_sta_config_stru conf = {0};
    /* 找到网络后复制网络信息和接入密码 */
    if (memcpy_s(g_target_ssid, WIFI_MAX_SSID_LEN, ssid, WIFI_MAX_SSID_LEN) != EOK) {
        return ERRCODE_MEMCPY;
    }
    if (memcpy_s(g_target_key, WIFI_MAX_KEY_LEN, key, strlen(key)) != EOK) {
        return ERRCODE_MEMCPY;
    }
    return Scan();
}
errcode_t ConnectToWifi(const char* ssid, int8_t *bssid,wifi_security_enum security_type,const char* key){
	EnableWifi();
	wifi_sta_config_stru conf = {0};
    /* 找到网络后复制网络信息和接入密码 */
    if (memcpy_s(conf.ssid, WIFI_MAX_SSID_LEN, ssid, WIFI_MAX_SSID_LEN) != EOK) {
        return ERRCODE_MEMCPY;
    }
    if (memcpy_s(conf.bssid, WIFI_MAC_LEN, bssid, WIFI_MAC_LEN) != EOK) {
        return ERRCODE_MEMCPY;
    }
    if (memcpy_s(conf.pre_shared_key, WIFI_MAX_KEY_LEN, key, strlen(key)) != EOK) {
        return ERRCODE_MEMCPY;
    }
    conf.security_type = security_type;
    conf.ip_type = DHCP; /* IP类型为动态DHCP获取 */
	return wifi_sta_connect(&conf);
}
errcode_t ConnectToWifiByScanInfo(wifi_scan_info_stru *info, const char *key){
	EnableWifi();
	return ConnectToWifi((char*)info->ssid,(const int8_t*) info->bssid, info->security_type, key);
}
size_t rl_wifi_GetScanInfoList(OB_VM* vm,long size){
	if(size <= 0){
		size = 10;
	}
	if(size > 100){
		size = 100;
	}
	size_t list_ptr = OB_New_List( vm , 1,"OB_List-rl_rl_wifi_GetScanInfoList");
	wifi_scan_info_stru *result = calloc(size,sizeof(wifi_scan_info_stru));
	WifiErrorCode r = wifi_sta_get_scan_info(result, &size);
	if(r!=0){
		free(result);
		return list_ptr;
	}
	for(int i =0;i<size;i++){
	    wifi_scan_info_stru * info = result + i;
		wifi_scan_info_stru * info_new = OB_malloc(vm,wifi_scan_info_stru,"WifiScanInfo",NULL);
		size_t info_ptr = GetOBPtrByNative(vm,(void*)info_new);
		memcpy_s(info_new,sizeof(wifi_scan_info_stru),info,sizeof(wifi_scan_info_stru));
		OB_Insert_Value_At_Index( vm, list_ptr, i,info_ptr);
	}
	free(result);
	return list_ptr;
}
#define WifiLinkedInfo wifi_linked_info_stru
static WifiLinkedInfo *connectedInfo;
static void onDHCP(struct netif *netif_p){
    AsyncMessage event_isr = {0};
    event_isr.msg.type = OB_Message_Type_EVENT;
    event_isr.msg.name = "OnWifiConnectionChanged";
    event_isr.msg.argType = "WifiLinkedInfo";
	WifiLinkedInfo *info_new = calloc(1,sizeof(WifiLinkedInfo));
	int e = memcpy_s(info_new,sizeof(WifiLinkedInfo),connectedInfo,sizeof(WifiLinkedInfo));
	if(0!=e){
		printf("memcpy_s fail %d\n",e);
	}
    event_isr.nativeObj = info_new;
	event_isr.nativeObjSize = sizeof(WifiLinkedInfo);
    LOS_TaskLock();
    UINT32 r = LOS_QueueWriteCopy(rs_queue_id,
                             &event_isr,
                             sizeof(AsyncMessage),
                             0);
    LOS_TaskUnlock();
}
static void OnWifiConnectionChanged(int32_t state, WifiLinkedInfo *info, int32_t reason_code){
	if(state!=1){
		printf("OnWifiConnectionChanged Unconnected\r\n");
		return;
	}
		printf("OnWifiConnectionChanged Connected\r\n");
	connectedInfo = info;
    // 联网业务开始
    struct netif* g_iface = netifapi_netif_find("wlan0");
    if (g_iface) {
		
		// netif_set_hostname(g_iface,"WS63");
    	// if (memcpy_s(g_iface->hostname, NETIF_HOSTNAME_MAX_LEN, "WS63", strlen("WS63")) != EOK) {
        // 	printf("memcpy_s(g_iface.hostname\r\n");
    	// }
		err_t ret = 0;
#if LWIP_NETIF_HOSTNAME
		ret = netifapi_set_hostname(g_iface, "WS63", strlen("WS63"));
        printf("netifapi_set_hostname: ret=%d\r\n", ret);
#endif
        ret = netifapi_dhcp_start(g_iface);
        printf("netifapi_dhcp_start: ret=%d\r\n", ret);
        osDelay(200); // wait DHCP server give me IP
        ret = netifapi_netif_common(g_iface, onDHCP, NULL);
    }else{
		printf("netifapi_netif_find fail\n");
	}
}
static void OnWifiScanStateChanged(int32_t state, int32_t size){
	if(state!=1){
		return;
	}
	if(strlen(g_target_ssid)>0){
		wifi_scan_info_stru *result = calloc(size,sizeof(wifi_scan_info_stru));
		WifiErrorCode r = wifi_sta_get_scan_info(result, &size);
		char founded = 0;
		if(r==0){
			for(int i =0;i<size;i++){
				wifi_scan_info_stru * info = result + i;
				if(0==strcmp((char*)info->ssid,g_target_ssid)){
					ConnectToWifiByScanInfo(info,g_target_key);
					founded = 1;
					break;
				}
			}
		}
		free(result);
		if(founded==0){
			Scan();
		}else{
			g_target_ssid[0] = 0;
		}
	}

    AsyncMessage event_isr = {0};
    event_isr.msg.type = OB_Message_Type_EVENT;
    event_isr.msg.name = "OnWifiScanStateChanged";
    event_isr.msg.argType = "Integer";
	event_isr.msg.arg.integer = size;
    LOS_TaskLock();
    UINT32 r = LOS_QueueWriteCopy(rs_queue_id,
                             &event_isr,
                             sizeof(AsyncMessage),
                             0);
    LOS_TaskUnlock();
	if(r!=LOS_OK){
		printf("OnWifiScanStateChanged error %d\n",r);
	}
}

// static int rl_AddDeviceConfig(char* ssid,char* password,WifiSecurityType security){
//     WifiErrorCode errCode;int g_netId = -1;
//     WifiDeviceConfig apConfig = {};
//     strcpy(apConfig.ssid, ssid);
//     strcpy(apConfig.preSharedKey,password);
//     apConfig.securityType = security;
// 	errCode = AddDeviceConfig(&apConfig, &g_netId);
// 	return g_netId;
// }
// static int rl_AddDeviceConfig_by_WifiScanInfo(WifiScanInfo info,char* password){
//     WifiErrorCode errCode;
// 	int g_netId = -1;
//     WifiDeviceConfig apConfig = {};
//     strcpy(apConfig.ssid, info.ssid);
//     strcpy(apConfig.preSharedKey,password);
//     apConfig.securityType = info.securityType;
// 	errCode = AddDeviceConfig(&apConfig, &g_netId);
// 	return g_netId;
// }

// static size_t rl_GetDeviceConfigs(OB_VM* vm){
//     WifiErrorCode errCode;
// 	size_t list_ptr = OB_New_List( vm , 0,"OB_List-rl_GetDeviceConfigs");
// 	WifiDeviceConfig result[WIFI_MAX_CONFIG_SIZE] = {};
// 	unsigned int size = WIFI_MAX_CONFIG_SIZE;
// 	errCode = GetDeviceConfigs(result, &size);
// 	if(errCode!=0){
// 		printf( "GetDeviceConfigs failed, errCode = %d\n", errCode);
// 		return list_ptr;
// 	}
// 	for(size_t i =0;i<size;i++){
// 		WifiDeviceConfig* r1 = calloc(1,sizeof(WifiDeviceConfig));
// 		memcpy_s(r1,sizeof(WifiDeviceConfig),&result[i],sizeof(WifiDeviceConfig));
// 		OB_Insert_Value_At_Index( vm,  list_ptr, i,r1);
// 	}
// 	return list_ptr;
// }
// static int bitAnd(int a, int b)
// {
//     return a & b;
// }
// static void GetDeviceMacAddressText(unsigned char *result)
// {
//     char buf[6] = {0};
//     int r = GetDeviceMacAddress(buf);
//     if (r == 0)
//     {
//         sprintf_s(result, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
//                   bitAnd(0xFF, buf[0]),
//                   bitAnd(0xFF, buf[1]),
//                   bitAnd(0xFF, buf[2]),
//                   bitAnd(0xFF, buf[3]),
//                   bitAnd(0xFF, buf[4]),
//                   bitAnd(0xFF, buf[5]));
//     }
//     else
//     {
//         sprintf_s(result, 18, "ERR:%d", r);
//         printf("ERR:%d", r);
//     }
// }
// static STR_PTR rl_GetIpAddr(OB_VM* vm){
// 	char ip_str[16] = {0};
// 	IpInfo info = {};
// 	int r = GetIpInfo(&info);
// 	if(r!=0){
// 		printf("GetIpInfo failed, errCode = %d\n", r);
// 	}else{
// 		uint_to_ipv4(info.ipAddress, ip_str);
// 	}
// 	return str2ptr(vm,ip_str);
// }
// static STR_PTR rl_GetNetMaskAddr(OB_VM* vm){
// 	char ip_str[16] = {0};
// 	IpInfo info = {};
// 	int r = GetIpInfo(&info);
// 	if(r!=0){
// 		printf("GetIpInfo failed, errCode = %d\n", r);
// 	}else{
// 		uint_to_ipv4(info.netMask, ip_str);
// 	}
// 	return str2ptr(vm,ip_str);
// }
// static STR_PTR rl_GetNetGateAddr(OB_VM* vm){
// 	char ip_str[16] = {0};
// 	IpInfo info = {};
// 	int r = GetIpInfo(&info);
// 	if(r!=0){
// 		printf("GetIpInfo failed, errCode = %d\n", r);
// 	}else{
// 		uint_to_ipv4(info.netGate, ip_str);
// 	}
// 	return str2ptr(vm,ip_str);
// }
#endif